﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Asistente.Model.Representation;
using Asistente.Model.General;

namespace Asistente.Model.COSMIC
{
    /// <summary>
    /// This class represents the COSMIC measurement model which contains a list of functional process
    /// </summary>
    public class CosmicModel : IMeasurable
    {
        private List<FunctionalProcess> appProcess;
        private Application app;


        public CosmicModel(Application app)
        {
            this.appProcess = new List<FunctionalProcess>();
            this.app = app;
        }

        public void addFunctionalProcess(FunctionalProcess fP)
        {
            appProcess.Add(fP);
        }

        public int Measure()
        {
            Int32 size = 0;
            foreach (FunctionalProcess fp in this.appProcess)
            {
                size = size + fp.Measure();
            }
            return size;

        }

        public override String ToString()
        {

            StringBuilder content = new StringBuilder();

            content.AppendLine("Application Name: " + app.Name);
            content.AppendLine("Total size: " + Measure());

            DateTime time = new DateTime(1, 1, 1, app.Hours, app.Minutes, app.Seconds);


            content.AppendLine("Elapsed time: " + time.ToString("T", System.Globalization.CultureInfo.CreateSpecificCulture("es-ES")));
            content.AppendLine("Mesurement average: " + MeasurementAverage() + "\n");
            content.AppendLine("Number of Functional Process found: " + this.appProcess.Count);
            content.AppendLine("Details: ");

            foreach (FunctionalProcess fp in this.appProcess)
            {
                fp.Sort();
                content.AppendLine("\tFunctional Process: " + fp.Name + " Size: " + fp.Measure());
                content.AppendLine(fp.ToString());
            }
            return content.ToString();

        }
        /// <summary>
        /// This Method generates an xml file containing the measuerement summary
        /// </summary>
        public void ExportAsXls(String fileName)
        {
            try
            {
                System.IO.StreamWriter file = new System.IO.StreamWriter(fileName);
                file.WriteLine("Application Name: \t" + app.Name);

                DateTime time = new DateTime(1, 1, 1, app.Hours, app.Minutes, app.Seconds);

                file.WriteLine("Elapsed time: \t" + time.ToString("T", System.Globalization.CultureInfo.CreateSpecificCulture("es-ES")));
                file.WriteLine("Total size: \t" + Measure());
                file.WriteLine("Mesurement average: \t" + MeasurementAverage() + "\n");

                file.WriteLine("Number of Functional Process found: \t" + this.appProcess.Count);
                file.WriteLine("\nSummary: ");

                foreach (FunctionalProcess fp in this.appProcess)
                {
                    fp.Sort();
                    file.WriteLine("Functional Process: \t" + fp.Name + "\t Size: " + fp.Measure());
                    file.WriteLine(fp.ToString());
                }
                file.Close();
            }
            catch (Exception)
            {

            }
        }
        public String ToHtml()
        {
            StringBuilder content = new StringBuilder();
            content.AppendLine("<head>");
            content.AppendLine("<b><font size='5' color='#0000A0'>COSMIC Measurement Summary</font></b>");
            content.AppendLine("<br>");
            content.AppendLine("<b><i><font size='4' color='#0000A0'> " + app.Name + "</font></i></b>");
            content.AppendLine("<br>");
            content.AppendLine("<br>");
            content.AppendLine("Total size: " + Measure() + " CFP");
            content.AppendLine("<br>");
            DateTime time = new DateTime(1, 1, 1, app.Hours, app.Minutes, app.Seconds);
            content.AppendLine("Elapsed time: " + time.ToString("T", System.Globalization.CultureInfo.CreateSpecificCulture("es-ES")));
            content.AppendLine("</br>");

            content.AppendLine("<br>");
            content.AppendLine("Mesurement average:  " + MeasurementAverage());
            content.AppendLine("</br>");
            content.AppendLine("</head>");

            content.AppendLine("<body>");
            content.AppendLine("<br>");
            content.AppendLine("<i>Number of Functional Process Found:</i> " + (this.appProcess.Count).ToString());
            content.AppendLine("</br>");

            content.AppendLine("<br>");
            content.AppendLine("<table border='1' cellpadding='5' cellspacing='5'>");
            content.AppendLine("<tr><td><b>Functional Process</b></td><td><b>Size</b></td></tr>");
            foreach (FunctionalProcess fp in this.appProcess)
            {
                content.AppendLine("<tr>");
                content.AppendLine("<td>"+fp.Name+"</td><td>"+fp.Measure()+"</td>");
                content.AppendLine("</tr>");
            }
            content.AppendLine("</br></table>");

            content.AppendLine("<br></br>");


            content.AppendLine("<br>");
            content.AppendLine("Details:");
            content.AppendLine("</br>");
         
            content.AppendLine("<br>");
            content.AppendLine("<table border='1' cellpadding='5' cellspacing='5'>");
            content.AppendLine("<tr><td><br><b>Functional Process</b></br></td><td><br><b>Move Type: </b></br></td><td><br><b>Interest Object</b></br></td></tr>");
            foreach (FunctionalProcess fp in appProcess)
            {
                //fp.Sort();
                content.Append("<tr>");
                content.Append(fp.ToHtml());
                content.AppendLine("</tr>");

            }
            content.AppendLine("</br></table>");
            content.AppendLine("</body>");
            return content.ToString();
            
        }
        /// <summary>
        /// This method calculates the CFP per hour of the application measurement
        /// </summary>
        /// <returns></returns>
        private Double MeasurementAverage()
        {
            Double minutesToHours = ((Double)app.Minutes / 60);
            Double secondToHours = ((Double)app.Seconds / 3600);
            Double hours = (Double)app.Hours;
            Double totalTime = hours + minutesToHours + secondToHours;
            Double average = (Double)Measure() / totalTime;
            return average;
        }
    }
}
